//
// Created by v on 19-8-7.
//

#include "CMCatchProcSys.h"
#include <exception>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/prctl.h>
#include <unistd.h>

#define LOGD(fmt, ...)                                                         \
    do                                                                         \
    {                                                                          \
        printf("%s:%d ", __func__, __LINE__);                                  \
        printf(fmt, ##__VA_ARGS__);                                            \
    } while (0)

typedef struct ATest
{
    int a;
};

void *thread_one(void *args)
{
    prctl(PR_SET_NAME, "threadone");
    ATest *a = NULL;
    while (true)
    {
        LOGD("do some thing\n");
        //        LOGD("%d\n", a->a);
        usleep(100000);
    }
    return NULL;
}

void *thread_two(void *args)
{
    prctl(PR_SET_NAME, "threadtwo");
    ATest *a = NULL;
    while (true)
    {
        LOGD("do some thing\n");
        try
        {
            LOGD("%d\n", a->a);
        }
        catch (std::exception e)
        {
            LOGD("e.x");
        }
        usleep(200000);
    }
    return NULL;
}

void SigActionFunc(int signum)
{
    switch (signum)
    {
    case SIGSEGV:
        LOGD("segvment fault\n");
        {
            CMCatchProcSys           ps(getpid());
            std::vector<ProcSysInfo> names;
            ps.getSigBlkNames(names);
            int i = 0;
            for (i = 0; i < names.size(); i++)
            {
                LOGD("[%d] => [%s,%s]\n", i, names[i].processName.c_str(),
                     names[i].sigBlk.c_str());
            }
        }
        sleep(5);
        //            exit(1);
        break;
    default:
        break;
    }
}

int main(int argc, char **args)
{
    struct sigaction sigact;
    sigact.sa_handler = SigActionFunc;
    sigact.sa_flags   = 0;
    sigaction(SIGSEGV, &sigact, NULL);

    pthread_t t1;
    pthread_create(&t1, NULL, thread_one, NULL);

    pthread_t t2;
    pthread_create(&t2, NULL, thread_two, NULL);

    ATest *a = NULL;
    while (true)
    {
        LOGD("I'm waiting\n");
        LOGD("[%d]\n", a->a);
        sleep(1);
    }
    return 0;
}
